#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
加密保护工具
功能：反编译保护、启动彩蛋、许可证验证
"""

import hashlib
import os
import time
import base64
from datetime import datetime
import sys
import threading

class AntiDecompile:
    """反编译保护类"""
    
    def __init__(self):
        self.license_key = self._generate_license()
        self.start_time = time.time()
        self.easter_egg_shown = False
        
    def _generate_license(self) -> str:
        """生成基于机器码的许可证"""
        # 获取机器唯一标识
        machine_id = self._get_machine_id()
        # 生成许可证
        license_key = hashlib.sha256(machine_id.encode()).hexdigest()[:16]
        return license_key
    
    def _get_machine_id(self) -> str:
        """获取机器唯一标识"""
        try:
            # Windows系统使用计算机名+处理器信息
            import platform
            import subprocess
            
            computer_name = platform.node()
            try:
                # 获取处理器信息
                result = subprocess.run(['wmic', 'cpu', 'get', 'ProcessorId'], 
                                      capture_output=True, text=True)
                processor_id = result.stdout.strip().split('\n')[-1].strip()
            except:
                processor_id = "default"
            
            return f"{computer_name}_{processor_id}"
        except:
            # 备用方案
            return "default_machine"
    
    def verify_integrity(self) -> bool:
        """验证程序完整性"""
        try:
            # 检查关键文件是否存在
            required_files = [
                "main.py",
                "src/controllers/serial_controller.py",
                "src/managers/config_manager.py"
            ]
            
            for file_path in required_files:
                if not os.path.exists(file_path):
                    return False
            
            # 检查文件大小（防止被修改）
            expected_sizes = {
                "main.py": 1000,  # 最小大小检查
            }
            
            for file_path, min_size in expected_sizes.items():
                if os.path.exists(file_path):
                    actual_size = os.path.getsize(file_path)
                    if actual_size < min_size:
                        return False
            
            return True
        except:
            return False
    
    def show_easter_egg(self):
        """显示启动彩蛋"""
        if self.easter_egg_shown:
            return
            
        self.easter_egg_shown = True
        
        # 彩蛋动画线程
        def easter_egg_animation():
            print("\n" * 2)
            print("╔══════════════════════════════════════════════════════════════╗")
            print("║                                                              ║")
            print("║              🔧 串口设备AT指令控制器 v2.0 🔧                  ║")
            print("║                                                              ║")
            print("║              💻 Powered by Zack Studio 💻                   ║")
            print("║                                                              ║")
            print("║              📧 Email: zack@example.com                    ║")
            print("║                                                              ║")
            print("║              🌟 专业 · 稳定 · 高效 🌟                      ║")
            print("║                                                              ║")
            print("╚══════════════════════════════════════════════════════════════╝")
            print("\n" * 1)
            time.sleep(2)  # 显示2秒后继续
            
        # 启动彩蛋线程
        egg_thread = threading.Thread(target=easter_egg_animation)
        egg_thread.daemon = True
        egg_thread.start()
        
        # 等待动画完成（最多3秒）
        egg_thread.join(timeout=3)
    
    def check_debugger(self) -> bool:
        """检查是否被调试"""
        try:
            # 检查是否有调试器附加
            if hasattr(sys, 'gettrace') and sys.gettrace() is not None:
                return True
            
            # 检查环境变量
            if 'PYDEVD_LOAD_VALUES_ASYNC' in os.environ:
                return True
            
            return False
        except:
            return False
    
    def protect_startup(self):
        """启动保护检查"""
        # 显示彩蛋
        self.show_easter_egg()
        
        # 检查调试器
        if self.check_debugger():
            print("⚠️  检测到调试环境，继续运行...")
        
        # 验证完整性
        if not self.verify_integrity():
            print("❌ 程序完整性验证失败，可能存在风险")
            return False
        
        return True
    
    def get_protection_info(self) -> dict:
        """获取保护信息"""
        return {
            "license_key": self.license_key,
            "machine_id": self._get_machine_id(),
            "protection_enabled": True,
            "debug_check": self.check_debugger(),
            "integrity_check": self.verify_integrity()
        }

class CodeObfuscator:
    """代码混淆工具"""
    
    @staticmethod
    def obfuscate_string(text: str) -> str:
        """混淆字符串"""
        # 简单的字符串混淆
        encoded = base64.b64encode(text.encode()).decode()
        return encoded
    
    @staticmethod
    def deobfuscate_string(obfuscated: str) -> str:
        """解混淆字符串"""
        try:
            decoded = base64.b64decode(obfuscated.encode()).decode()
            return decoded
        except:
            return ""
    
    @staticmethod
    def create_watermark():
        """创建程序水印"""
        watermark = {
            "created_by": "Zack Studio",
            "version": "2.0",
            "timestamp": datetime.now().isoformat(),
            "type": "Serial AT Controller"
        }
        return watermark

# 全局保护实例
anti_decompile = AntiDecompile()

# 启动保护装饰器
def protected_startup(func):
    """启动保护装饰器"""
    def wrapper(*args, **kwargs):
        # 执行保护检查
        if anti_decompile.protect_startup():
            return func(*args, **kwargs)
        else:
            print("❌ 启动保护检查失败")
            return None
    return wrapper